$(function () {
	
	init_objects();
	
	//defining variables for dropping areas
  	var canvas = document.querySelector('#canvas'),
  		leftPanel = document.querySelector('#left-panel'),
  		rightPanel = document.querySelector('#right-panel'),
  		topPanel = document.querySelector('#top-panel'),
  		bottomPanel = document.querySelector('#bottom-panel');
	
	var links = document.querySelectorAll('li > img'), el = null;
	var bRect = canvas.getBoundingClientRect();
	
	//setting all draggable parts
  	for (var i = 0; i < links.length; i++) {
 	   	el = links[i];

		addEvent(el, 'mousedown', function (e) {		
			if ((e.clientX >= bRect.left) && (e.clientX <= bRect.right) && 
				(e.clientY <= bRect.bottom)&&(e.clientY >= bRect.top)) {
				var mouseX = (e.clientX- bRect.left);
				var mouseY = (e.clientY - bRect.top);
			
				var x = this.style.left;
				var y = this.style.top;
				this.dataset.datax = mouseX-x.slice(0,x.length-2);
				this.dataset.datay = mouseY-y.slice(0,y.length-2);
			}
			else {
				this.dataset.datax = 0;
				this.dataset.datay = 0;
			}
			
		});

		addEvent(el, 'dragstart', function (e) {
	      		e.dataTransfer.effectAllowed = 'move'; // only dropEffect='copy' will be dropable
	      		e.dataTransfer.setData('Text', this.id); // required otherwise doesn't work
			
			//el.setAttribute('draggable', 'true');
			//getting mouse position correctly	
			
			e.dataTransfer.setData('PosX', this.dataset.datax);
			e.dataTransfer.setData('PosY', this.dataset.datay);		
	    	});
  	}


  	/*** adding drag-n-drop effects to each panels and canvas ***/

	//adding a handler for 'dragover' event (aka what happens when you are dragging an element over canvas)
  	addEvent(canvas, 'dragover', function (e) {
	    	if (e.preventDefault)
			e.preventDefault(); // allows us to drop	

	   	this.className = 'over';
		e.dataTransfer.dropEffect = 'move';

		return false;
  	});

  	// to get IE to work
  	addEvent(canvas, 'dragenter', function (e) {
		this.className = 'over';
		return false;
  	});

	//what happens when element is dragged out of canvas
  	addEvent(canvas, 'dragleave', function () {
		this.className = '';
  	});

	//adding a handler for 'drop' event
  	addEvent(canvas, 'drop', function (e) {
		if (e.stopPropagation)
			e.stopPropagation(); // stops the browser from redirecting...why???
		
		//getting the dragging element
    		var el = document.getElementById(e.dataTransfer.getData('Text')),
			dragX = e.dataTransfer.getData('PosX'),
			dragY = e.dataTransfer.getData('PosY');
    	
	    	//getting coordinates for precise positioning
    		var coords = getCoords(this),
    			imgWidth = parseInt(el.clientWidth/2),
    			imgHeight = parseInt(el.clientHeight/2),
    			scrollTop = document.body.scrollTop,
    			scrollLeft = document.body.scrollLeft;
    	
		//getting mouse position correctly 
		mouseX = (e.clientX - bRect.left);
		mouseY = (e.clientY - bRect.top);
		
		//console.log(bRect.left+":"+bRect.right+";;"+mouseY+"+"+mouseY);
		
		
    		//moving element to canvas with precise positioning
	    	canvas.appendChild(el);

    		el.style.left = mouseX-dragX+'px';
	    	el.style.top = mouseY-dragY+'px';

		//for debug
    		//console.log(dragX+"; "+dragY+"; "+imgHeight);
		//console.log(el.style.top);

    		//el.parentNode.removeChild(el);
	});
	
	//now the same handlers for the left panel
	
	//adding a handler for 'dragover' event (aka what happens when you are dragging an element over canvas)
  	addEvent(leftPanel, 'dragover', function (e) {
	    	if (e.preventDefault)
			e.preventDefault(); // allows us to drop	

    		this.className = 'over';
	    	e.dataTransfer.dropEffect = 'move';

	    	return false;
  	});

  	// to get IE to work
  	addEvent(leftPanel, 'dragenter', function (e) {
	    	this.className = 'over';
    		return false;
  	});

	//what happens when element is dragged out of panel
  	addEvent(leftPanel, 'dragleave', function () {
		this.className = '';
  	});

	//adding a handler for 'drop' event
  	addEvent(leftPanel, 'drop', function (e) {
		if (e.stopPropagation)
			e.stopPropagation(); // stops the browser from redirecting...why???
		
		//getting the dragging element
		var el = document.getElementById(e.dataTransfer.getData('Text')),
    			children = leftPanel.children,
    			tmp	= 0;
    	
 	   	//moving element to an empty <li> inside left-panel
    		for (var i = children.length-1; i >= 0 ; i--) {
    			if (children[i].innerHTML == "")
    				tmp = i;
		}

	    	leftPanel.children[tmp].appendChild(el);
	    	el.style.left ='';
	    	el.style.top = '';
	});
	
	//and for the right panel
	
	//adding a handler for 'dragover' event (aka what happens when you are dragging an element over canvas)
  	addEvent(rightPanel, 'dragover', function (e) {
    		if (e.preventDefault) e.preventDefault(); // allows us to drop	
			this.className = 'over';
		
		e.dataTransfer.dropEffect = 'move';
		return false;
  	});

  	// to get IE to work
  	addEvent(rightPanel, 'dragenter', function (e) {
    		this.className = 'over';
    		return false;
  	});

	//what happens when element is dragged out of panel
  	addEvent(rightPanel, 'dragleave', function () {
    		this.className = '';
  	});

	//adding a handler for 'drop' event
  	addEvent(rightPanel, 'drop', function (e) {
    		if (e.stopPropagation)
			e.stopPropagation(); // stops the browser from redirecting...why???
		
		//getting the dragging element
    		var el = document.getElementById(e.dataTransfer.getData('Text')),
			children = rightPanel.children,
			tmp	= 0;
    	
		//moving element to an empty <li> inside right-panel
    		for (var i = children.length-1; i >= 0 ; i--) {
    			if (children[i].innerHTML == "")
    				tmp = i;
		}

    		rightPanel.children[tmp].appendChild(el);
    		el.style.left ='';
    		el.style.top = '';    	
	});
	
	//for the top panel
	
	//adding a handler for 'dragover' event (aka what happens when you are dragging an element over canvas)
  	addEvent(topPanel, 'dragover', function (e) {
		if (e.preventDefault)
			e.preventDefault(); // allows us to drop

		this.className = 'over';

    		e.dataTransfer.dropEffect = 'move';
		return false;
  	});

  	// to get IE to work
  	addEvent(topPanel, 'dragenter', function (e) {
		this.className = 'over';
		return false;
  	});

	//what happens when element is dragged out of panel
  	addEvent(topPanel, 'dragleave', function () {
		this.className = '';
  	});

	//adding a handler for 'drop' event
  	addEvent(topPanel, 'drop', function (e) {
    		if (e.stopPropagation)
			e.stopPropagation(); // stops the browser from redirecting...why???
		
		//getting the dragging element
	    	var el = document.getElementById(e.dataTransfer.getData('Text')),
			children = topPanel.children,
			tmp	= 0;
    	
	    	//moving element to an empty <li> inside right-panel
    		for (var i = children.length-1; i >= 0 ; i--) {
    			if (children[i].innerHTML == "")
    				tmp = i;
		}
    		
		topPanel.children[tmp].appendChild(el);
		el.style.left ='';
		el.style.top = '';
	});
	
	//and for the bottom panel
	
	//adding a handler for 'dragover' event (aka what happens when you are dragging an element over canvas)
  	addEvent(bottomPanel, 'dragover', function (e) {
		if (e.preventDefault)
			e.preventDefault(); // allows us to drop
		
		this.className = 'over';
	    	e.dataTransfer.dropEffect = 'move';

		return false;
  	});

  	// to get IE to work
  	addEvent(bottomPanel, 'dragenter', function (e) {
		this.className = 'over';
		return false;
  	});

	//what happens when element is dragged out of panel
  	addEvent(bottomPanel, 'dragleave', function () {
		this.className = '';
  	});

	//adding a handler for 'drop' event
  	addEvent(bottomPanel, 'drop', function (e) {
		if (e.stopPropagation)
			e.stopPropagation(); // stops the browser from redirecting...why???
		
		//getting the dragging element
		var el = document.getElementById(e.dataTransfer.getData('Text')),
    			children = bottomPanel.children,
    			tmp	= 0;
    	
	    	//moving element to an empty <li> inside right-panel
    		for (var i = children.length-1; i >= 0 ; i--) {
			if (children[i].innerHTML == "")
    				tmp = i;
		}
		
		bottomPanel.children[tmp].appendChild(el);
		el.style.left ='';
		el.style.top = '';
	});

});

//initializing objects
function init_objects() {
	
}


//checking the layout
function check_scheme() {
	
	var canvas = document.getElementById('canvas');
	var children = canvas.children;
	var channel = 0, eve = 0;
	
	var elements = {};
	
	for (var i = 0; i < children.length; i++) {
		if (elements[children[i].className] == undefined) {
			elements[children[i].className] = [];
			
		}
		
		//if there is a classic channel on canvas 
		if (children[i].className == 'channel') channel = 1;
		if (children[i].className == 'eve') eve = 1;
		
		var elem = elements[children[i].className];
		var coords = getCoords(children[i]),
			tmp;
				
		elem[elem.length] = {};
		elem[elem.length-1]["name"] = children[i].id;
		elem[elem.length-1]["coords"] = coords;
		elem[elem.length-1]["width"] = children[i].clientWidth;
		elem[elem.length-1]["height"] = children[i].clientHeight;
		
	}	
	
	for (var i in elements) {
		for (var j in elements)
			if (i != j) {
				for (var k = 0; k < elements[j].length; k++) {
				var match = matches(elements[i], elements[j][k]);
				if (match) {
					if (!elements[j][k]["link"])
						elements[j][k]["link"] = [];
					
					for (var t = 0; t < match; t++)
						elements[j][k]["link"].push(i);
					
					 
					}
				}
			}
	}
	
	var good = [1,1];
	
	var MODELS = [BB84_MODEL, BB84_MODEL1];
	
	for (var l = 0; l < MODELS.length; l++){
	
	for (var i in MODELS[l]) {
		var tmp = MODELS[l][i];
		
		if (elements[tmp.name] != undefined) {
		
		for (var j = 0; j < elements[tmp.name].length; j++) {
			if ((elements[tmp.name][j] != undefined) && (elements[tmp.name][j].link != undefined)) {
				if (((elements[tmp.name][j].link).sort().join() != (tmp.link).sort().join()) && ((elements[tmp.name][j].link).sort().join() != (tmp.link2).sort().join())) {
						good[l] = 0;
				}
			}
			else good[l] = 0;							
		}			
	}
	}
	
		//check for empty canvas
		if ((elem == undefined) || (children.length < 2)) good = 0;
	
	}
	
	if (eve) document.getElementById(".isEugene").checked = "checked";
	else document.getElementById(".isEugene").checked = "";
	
	//continue from this place, judging from the value of good
	var response = (good[0] || good[1]) && channel;
	if (response) $('#goodModal').modal();
	else $('#badModal').modal();
	//alert(response);
}

function matches(obj1, obj2) {
	var m = 0;
	
	for (var i = 0; i < obj1.length; i++) {
	if ((obj1[i].coords.left + obj1[i].width > obj2.coords.left ) && (obj1[i].coords.left < obj2.coords.left )) {
		if ((obj1[i].coords.top + obj1[i].height > obj2.coords.top) && (obj1[i].coords.top < obj2.coords.top + obj2.height)) {
			m++;
		}
		else if ((obj2.coords.top + obj2.height > obj1[i].coords.top) && (obj2.coords.top < obj1[i].coords.top + obj1[i].height)) {
			m++
		}
	}
	
	else if ((obj2.coords.left + obj2.width > obj1[i].coords.left ) && (obj2.coords.left < obj1[i].coords.left )) {
		if ((obj1[i].coords.top + obj1[i].height > obj2.coords.top) && (obj1[i].coords.top < obj2.coords.top + obj2.height)) {
			m++;
		}
		else if ((obj2.coords.top + obj2.height > obj1[i].coords.top) && (obj2.coords.top < obj1[i].coords.top + obj1[i].height)) {
			m++
		}
	}
	
	}
	
	return m;
}

var BB84_MODEL = {
	couplers: {
		name: 'coupler',
		number: 2,
		link: ['detector', 'line'],
		link2: ['source', 'line']
	}
}

var BB84_MODEL1 = {
	sources: {
		name: 'source',
		number: 2,
		link: ['coupler'],
		link2: ['coupler','channel']
	},
	
	detectors: {
		name: 'detector',
		number: 2,
		link: ['coupler'],
		link2: ['coupler', 'channel']
	},
	
	couplers: {
		name: 'coupler',
		number: 2,
		link: ['detector','detector','line'],
		link2: ['line','source','source']
	},
	
	lines: {
		name: 'line',
		number: 1,
		link: ['coupler','coupler'],
		link2: ['coupler', 'coupler']
	},
	
	channels: {
		name: 'classicChannel',
		number: 1,
		link: ['source','detector'],
		link2: ['detector','source']
	}
};

var BB84_MODEL2 = {
	
	sources: {
		name: 'source',
		number: 2
	},
	
	detectors: {
		name: 'detector',
		number: 2
	},
	
	couplers: {
		name: 'coupler',
		number: 2
	},
	
	eveRepeater: {
		name: 'eveRepeater',
		number: 1
	},
	
	lines: {
		name: 'line',
		number: 2
	},
	
	channels: {
		name: 'classicChannel',
		number: 1
	}
};
